<!--
  - @copyright Copyright (c) 2020 Julien Veyssier <eneiluj@posteo.net>
  -
  - @author Julien Veyssier <eneiluj@posteo.net>
  -
  - @license GNU AGPL version 3 or any later version
  -
  - This program is free software: you can redistribute it and/or modify
  - it under the terms of the GNU Affero General Public License as
  - published by the Free Software Foundation, either version 3 of the
  - License, or (at your option) any later version.
  -
  - This program is distributed in the hope that it will be useful,
  - but WITHOUT ANY WARRANTY; without even the implied warranty of
  - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  - GNU Affero General Public License for more details.
  -
  - You should have received a copy of the GNU Affero General Public License
  - along with this program. If not, see <http://www.gnu.org/licenses/>.
-->

<template>
	<div class="matterbridge-settings">
		<div v-if="loading" class="loading" />
		<div v-show="!loading">
			<div id="matterbridge-header">
				<p>
					{{ t('spreed', 'You can bridge channels from various instant messaging systems with Matterbridge.') }}
					<a href="https://github.com/42wim/matterbridge/wiki" target="_blank" rel="noopener">
						<span class="icon icon-external" />
						{{ t('spreed', 'More info on Matterbridge') }}
					</a>
				</p>
			</div>
			<div class="basic-settings">
				<div v-show="!enabled"
					class="add-part-wrapper">
					<span class="icon icon-add" />
					<Multiselect
						ref="partMultiselect"
						v-model="selectedType"
						label="displayName"
						track-by="type"
						:placeholder="newPartPlaceholder"
						:options="formatedTypes"
						:user-select="true"
						:internal-search="true"
						@input="clickAddPart">
						<template #option="{option}">
							<img class="icon-multiselect-service"
								:src="option.iconUrl">
							{{ option.displayName }}
						</template>
					</Multiselect>
				</div>
				<div v-show="parts.length > 0"
					class="enable-switch-line">
					<input
						id="enable-checkbox"
						type="checkbox"
						class="checkbox"
						:token="token"
						:checked="enabled"
						@change="onEnabled">
					<label for="enable-checkbox">
						{{ t('spreed', 'Enable bridge') }}
						({{ processStateText }})
					</label>
					<button
						v-if="enabled"
						v-tooltip.top="{ content: t('spreed', 'Show Matterbridge log') }"
						class="icon icon-edit"
						@click="showLogContent" />
					<Modal v-if="logModal"
						@close="closeLogModal">
						<div class="modal__content">
							<textarea v-model="processLog" class="log-content" />
						</div>
					</Modal>
				</div>
			</div>
			<ul>
				<li v-for="(part, i) in parts" :key="part.type + i">
					<BridgePart
						:num="i+1"
						:part="part"
						:type="types[part.type]"
						:editing="part.editing"
						:editable="!enabled"
						@edit-clicked="onEditClicked(i)"
						@delete-part="onDelete(i)" />
				</li>
			</ul>
		</div>
	</div>
</template>

<script>
import {
	editBridge,
	getBridge,
	getBridgeProcessState,
} from '../../../services/matterbridgeService'
import { showSuccess } from '@nextcloud/dialogs'
import { imagePath } from '@nextcloud/router'
import Multiselect from '@nextcloud/vue/dist/Components/Multiselect'
import Modal from '@nextcloud/vue/dist/Components/Modal'
import BridgePart from './BridgePart'

import Vue from 'vue'
import { Tooltip } from '@nextcloud/vue'
Vue.directive('tooltip', Tooltip)

export default {
	name: 'MatterbridgeSettings',
	components: {
		Multiselect,
		BridgePart,
		Modal,
	},

	mixins: [
	],

	props: {
	},

	data() {
		return {
			enabled: false,
			parts: [],
			loading: false,
			processRunning: null,
			processLog: '',
			logModal: false,
			stateLoop: null,
			types: {
				nctalk: {
					name: 'Nextcloud Talk',
					iconUrl: imagePath('spreed', 'app-dark.svg'),
					infoTarget: 'https://github.com/42wim/matterbridge/wiki/Section-Nextcloud-Talk-%28basic%29',
					fields: {
						server: {
							type: 'url',
							placeholder: t('spreed', 'Nextcloud URL'),
							icon: 'icon-link',
						},
						login: {
							type: 'text',
							placeholder: t('spreed', 'Nextcloud user'),
							icon: 'icon-user',
						},
						password: {
							type: 'password',
							placeholder: t('spreed', 'User password'),
							icon: 'icon-category-auth',
						},
						channel: {
							type: 'text',
							placeholder: t('spreed', 'Talk conversation'),
							icon: 'icon-group',
						},
					},
					mainField: 'server',
				},
				matrix: {
					name: 'Matrix',
					iconUrl: imagePath('spreed', 'bridge-services/matrix.svg'),
					infoTarget: 'https://github.com/42wim/matterbridge/wiki/Settings#matrix',
					fields: {
						server: {
							type: 'url',
							placeholder: t('spreed', 'Matrix server URL'),
							icon: 'icon-link',
						},
						login: {
							type: 'text',
							placeholder: t('spreed', 'User'),
							icon: 'icon-user',
						},
						password: {
							type: 'password',
							placeholder: t('spreed', 'User password'),
							icon: 'icon-category-auth',
						},
						channel: {
							type: 'text',
							placeholder: t('spreed', 'Matrix channel'),
							icon: 'icon-group',
						},
					},
					mainField: 'server',
				},
				mattermost: {
					name: 'Mattermost',
					iconUrl: imagePath('spreed', 'bridge-services/mattermost.svg'),
					infoTarget: 'https://github.com/42wim/matterbridge/wiki/Settings#mattermost',
					fields: {
						server: {
							type: 'url',
							placeholder: t('spreed', 'Mattermost server URL'),
							icon: 'icon-link',
						},
						login: {
							type: 'text',
							placeholder: t('spreed', 'Mattermost user'),
							icon: 'icon-user',
						},
						password: {
							type: 'password',
							placeholder: t('spreed', 'User password'),
							icon: 'icon-category-auth',
						},
						team: {
							type: 'text',
							placeholder: t('spreed', 'Team name'),
							icon: 'icon-group',
						},
						channel: {
							type: 'text',
							placeholder: t('spreed', 'Channel name'),
							icon: 'icon-group',
						},
					},
					mainField: 'server',
				},
				rocketchat: {
					name: 'Rocket.Chat',
					iconUrl: imagePath('spreed', 'bridge-services/rocketchat.svg'),
					infoTarget: 'https://github.com/42wim/matterbridge/wiki/Settings#rocketchat',
					fields: {
						server: {
							type: 'url',
							placeholder: t('spreed', 'Rocket.Chat server URL'),
							icon: 'icon-link',
						},
						login: {
							type: 'text',
							placeholder: t('spreed', 'User name or e-mail address'),
							icon: 'icon-user',
						},
						password: {
							type: 'password',
							placeholder: t('spreed', 'Password'),
							icon: 'icon-category-auth',
						},
						channel: {
							type: 'text',
							placeholder: t('spreed', 'Rocket.Chat channel'),
							icon: 'icon-group',
						},
					},
					mainField: 'server',
				},
				zulip: {
					name: 'Zulip',
					iconUrl: imagePath('spreed', 'bridge-services/zulip.svg'),
					infoTarget: 'https://github.com/42wim/matterbridge/wiki/Settings#zulip',
					fields: {
						server: {
							type: 'url',
							placeholder: t('spreed', 'Zulip server URL'),
							icon: 'icon-link',
						},
						login: {
							type: 'text',
							placeholder: t('spreed', 'Bot user name'),
							icon: 'icon-user',
						},
						token: {
							type: 'password',
							placeholder: t('spreed', 'Bot API key'),
							icon: 'icon-category-auth',
						},
						channel: {
							type: 'text',
							placeholder: t('spreed', 'Zulip channel'),
							icon: 'icon-group',
						},
					},
					mainField: 'server',
				},
				slack: {
					name: 'Slack',
					iconUrl: imagePath('spreed', 'bridge-services/slack.svg'),
					infoTarget: 'https://github.com/42wim/matterbridge/wiki/Slack-bot-setup',
					fields: {
						token: {
							type: 'password',
							placeholder: t('spreed', 'API token'),
							icon: 'icon-category-auth',
						},
						channel: {
							type: 'text',
							placeholder: t('spreed', 'Slack channel'),
							icon: 'icon-group',
						},
					},
					mainField: 'channel',
				},
				discord: {
					name: 'Discord',
					iconUrl: imagePath('spreed', 'bridge-services/discord.svg'),
					infoTarget: 'https://github.com/42wim/matterbridge/wiki/Discord-bot-setup',
					fields: {
						token: {
							type: 'password',
							placeholder: t('spreed', 'API token'),
							icon: 'icon-category-auth',
						},
						server: {
							type: 'text',
							placeholder: t('spreed', 'Server ID or name'),
							icon: 'icon-group',
						},
						channel: {
							type: 'text',
							placeholder: t('spreed', 'Channel ID or name'),
							icon: 'icon-group',
						},
					},
					mainField: 'server',
				},
				telegram: {
					name: 'Telegram',
					iconUrl: imagePath('spreed', 'bridge-services/telegram.svg'),
					infoTarget: 'https://github.com/42wim/matterbridge/wiki/Settings#telegram',
					fields: {
						token: {
							type: 'password',
							placeholder: t('spreed', 'API token'),
							icon: 'icon-category-auth',
						},
						channel: {
							type: 'text',
							placeholder: t('spreed', 'Channel'),
							icon: 'icon-group',
						},
					},
					mainField: 'chatid',
				},
				steam: {
					name: 'Steam',
					iconUrl: imagePath('spreed', 'bridge-services/steam.svg'),
					infoTarget: 'https://github.com/42wim/matterbridge/wiki/Settings#steam',
					fields: {
						login: {
							type: 'text',
							placeholder: t('spreed', 'Login'),
							icon: 'icon-user',
						},
						password: {
							type: 'password',
							placeholder: t('spreed', 'Password'),
							icon: 'icon-category-auth',
						},
						channel: {
							type: 'text',
							placeholder: t('spreed', 'Chat ID'),
							icon: 'icon-group',
						},
					},
					mainField: 'chatid',
				},
				irc: {
					name: 'IRC',
					iconUrl: imagePath('spreed', 'bridge-services/irc.svg'),
					infoTarget: 'https://github.com/42wim/matterbridge/wiki/Settings#irc',
					fields: {
						server: {
							type: 'url',
							placeholder: t('spreed', 'IRC server URL (e.g. chat.freenode.net:6667)'),
							icon: 'icon-link',
						},
						nick: {
							type: 'text',
							placeholder: t('spreed', 'Nickname'),
							icon: 'icon-user',
						},
						password: {
							type: 'password',
							placeholder: t('spreed', 'Connection password'),
							icon: 'icon-category-auth',
						},
						channel: {
							type: 'text',
							placeholder: t('spreed', 'IRC channel'),
							icon: 'icon-group',
						},
						channelpassword: {
							type: 'password',
							placeholder: t('spreed', 'Channel password'),
							icon: 'icon-category-auth',
						},
						nickservnick: {
							type: 'text',
							placeholder: t('spreed', 'NickServ nickname'),
							icon: 'icon-user',
						},
						nickservpassword: {
							type: 'password',
							placeholder: t('spreed', 'NickServ password'),
							icon: 'icon-category-auth',
						},
						usetls: {
							type: 'checkbox',
							labelText: t('spreed', 'Use TLS'),
						},
						usesasl: {
							type: 'checkbox',
							labelText: t('spreed', 'Use SASL'),
						},
						skiptls: {
							type: 'checkbox',
							labelText: t('spreed', 'Skip TLS verification'),
						},
					},
					mainField: 'channel',
				},
				msteams: {
					name: 'Microsoft Teams',
					iconUrl: imagePath('spreed', 'bridge-services/msteams.svg'),
					infoTarget: 'https://github.com/42wim/matterbridge/wiki/MS-Teams-setup',
					fields: {
						tenantid: {
							type: 'text',
							placeholder: t('spreed', 'Tenant ID'),
							icon: 'icon-user',
						},
						clientid: {
							type: 'password',
							placeholder: t('spreed', 'Client ID'),
							icon: 'icon-user',
						},
						teamid: {
							type: 'text',
							placeholder: t('spreed', 'Team ID'),
							icon: 'icon-category-auth',
						},
						channel: {
							type: 'text',
							placeholder: t('spreed', 'Thread ID'),
							icon: 'icon-group',
						},
					},
					mainField: 'threadid',
				},
				xmpp: {
					name: 'XMPP/Jabber',
					iconUrl: imagePath('spreed', 'bridge-services/xmpp.svg'),
					infoTarget: 'https://github.com/42wim/matterbridge/wiki/Settings#xmpp',
					fields: {
						server: {
							type: 'url',
							placeholder: t('spreed', 'XMPP/Jabber server URL'),
							icon: 'icon-link',
						},
						muc: {
							type: 'url',
							placeholder: t('spreed', 'MUC server URL'),
							icon: 'icon-link',
						},
						jid: {
							type: 'text',
							placeholder: t('spreed', 'Jabber ID'),
							icon: 'icon-user',
						},
						nick: {
							type: 'text',
							placeholder: t('spreed', 'Nickname'),
							icon: 'icon-user',
						},
						password: {
							type: 'password',
							placeholder: t('spreed', 'Password'),
							icon: 'icon-category-auth',
						},
						channel: {
							type: 'text',
							placeholder: t('spreed', 'Channel'),
							icon: 'icon-group',
						},
					},
					mainField: 'channel',
				},
			},
			newPartPlaceholder: t('spreed', 'Add new bridged channel to current conversation'),
			selectedType: null,
		}
	},

	computed: {
		show() {
			return this.$store.getters.getSidebarStatus
		},
		opened() {
			return !!this.token && this.show
		},
		token() {
			const token = this.$store.getters.getToken()
			this.getBridge(token)
			this.relaunchStateLoop(token)
			return token
		},
		formatedTypes() {
			return Object.keys(this.types).map((k) => {
				const t = this.types[k]
				return {
					displayName: t.name,
					type: k,
					iconUrl: t.iconUrl,
				}
			})
		},
		processStateText() {
			return this.processRunning === null
				? t('spreed', 'unknown state')
				: this.processRunning
					? t('spreed', 'running')
					: this.enabled
						? t('spreed', 'not running, check Matterbridge log')
						: t('spreed', 'not running')
		},
	},

	beforeMount() {
	},

	beforeDestroy() {
	},

	methods: {
		relaunchStateLoop(token) {
			// start loop to periodically get bridge state
			clearInterval(this.stateLoop)
			this.stateLoop = setInterval(() => this.getBridgeProcessState(token), 60000)
		},
		clickAddPart() {
			const typeKey = this.selectedType.type
			const type = this.types[typeKey]
			const newPart = {
				type: typeKey,
				editing: true,
			}
			for (const fieldKey in type.fields) {
				newPart[fieldKey] = ''
			}
			this.parts.unshift(newPart)
			this.selectedType = null
		},
		onDelete(i) {
			this.parts.splice(i, 1)
			this.save()
		},
		onEditClicked(i) {
			this.parts[i].editing = !this.parts[i].editing
			if (!this.parts[i].editing) {
				this.save()
			}
		},
		onEnabled(e) {
			this.enabled = e.target.checked
			this.save()
		},
		save() {
			if (this.parts.length === 0) {
				this.enabled = false
			}
			this.editBridge(this.token, this.enabled, this.parts)
		},
		async getBridge(token) {
			this.loading = true
			try {
				const result = await getBridge(token)
				const bridge = result.data.ocs.data
				this.enabled = bridge.enabled
				this.parts = bridge.parts
				this.processLog = bridge.log
				this.processRunning = bridge.running
			} catch (exception) {
				console.error(exception)
			}
			this.loading = false
		},
		async editBridge() {
			this.loading = true
			this.parts.forEach(part => {
				part.editing = false
			})
			try {
				const result = await editBridge(this.token, this.enabled, this.parts)
				this.processLog = result.data.ocs.data.log
				this.processRunning = result.data.ocs.data.running
				showSuccess(t('spreed', 'Bridge saved'))
			} catch (exception) {
				console.error(exception)
			}
			this.loading = false
		},
		async getBridgeProcessState(token) {
			try {
				const result = await getBridgeProcessState(token)
				this.processLog = result.data.ocs.data.log
				this.processRunning = result.data.ocs.data.running
			} catch (exception) {
				console.error(exception)
			}
		},
		showLogContent() {
			this.getBridgeProcessState(this.token)
			this.logModal = true
		},
		closeLogModal() {
			this.logModal = false
		},
	},
}
</script>

<style lang="scss" scoped>
::v-deep .icon-multiselect-service {
	width: 16px !important;
	height: 16px !important;
	margin-right: 10px;
}

body.theme--dark .icon-multiselect-service {
	-webkit-filter: invert(1);
	filter: invert(1);
}

.matterbridge-settings {
	.loading {
		margin-top: 30px;
	}

	h3 {
		font-weight: bold;
		padding: 0;
		height: 44px;
		display: flex;

		p {
			margin-top: auto;
			margin-bottom: auto;
		}

		.icon {
			display: inline-block;
			width: 40px;
		}
		&:hover {
			background-color: var(--color-background-hover);
		}
	}

	#matterbridge-header {
		padding: 0 0 10px 0;

		p {
			color: var(--color-text-maxcontrast);

			a:hover,
			a:focus {
				border-bottom: 2px solid var(--color-text-maxcontrast);
			}

			a .icon {
				display: inline-block;
				margin-bottom: -3px;
			}
		}
	}

	.basic-settings {
		.action {
			list-style: none;
		}
		.save-changes {
			width: 100%;
			text-align: left;

			.icon-checkmark {
				margin: 0 10px 0 2px;
			}
		}
		.multiselect {
			width: calc(100% - 46px);
		}
		.icon {
			display: inline-block;
			width: 40px;
			height: 34px;
			background-position: 14px center;
		}
		.add-part-wrapper {
			margin-top: 5px;
		}
		.enable-switch-line {
			display: flex;
			height: 44px;

			label {
				flex-grow: 1;
				margin-top: auto;
				margin-bottom: auto;
				&::before {
					margin: 0 10px 0 15px;
				}
			}
			button {
				opacity: 0.5;
				width: 44px;
				height: 44px;
				border-radius: var(--border-radius-pill);
				background-color: transparent;
				border: none;
				margin: 0;

				&:hover,
				&:focus {
					opacity: 1;
					background-color: var(--color-background-hover);
				}
			}
		}
	}

	ul {
		margin-bottom: 64px;
	}
}

.log-content {
	width: 600px;
	height: 400px;
}
</style>
